home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- VGLFLI.C
-
- Simple (and slow) C routine to play a 320x200 .FLI file. You specify the
- filename of the flick to be played, a pointer to a screen buffer, and a
- speed (in clock ticks). If the screen buffer you specify is VIDMEM, you may
- get some shearing but it'll probably be faster. Anything other than VIDMEM
- means vglUpdateW is called to update video memory with each frame. No
- flicker, but slower (usually).
-
- This is an example of lousy coding. It is slow. I wrote it a long time ago
- and just found it again the other day. I'm throwing it into the soup
- because it may be of some use to someone.
-
- This will play the .FLI in a loop until any key is pressed.
-
- Mark
- morley@camosun.bc.ca
- *****************************************************************************/
-
- #include <stdio.h>
- #include <dos.h>
- #include <time.h>
-
- #define BUFSIZE 8192 /* Maximum buffer to try and */
- /* allocate for file reading. */
-
- static char far Pal[768]; /* Our palette buffer */
- static char* VBuf; /* Will point to an I/O buffer */
-
- #define FLI_COLOR 11 /* Types of FLI chunks */
- #define FLI_LC 12
- #define FLI_BLACK 13
- #define FLI_BRUN 15
- #define FLI_COPY 16
-
- typedef struct /* The structure of a .FLI header */
- {
- unsigned long size;
- unsigned int magic;
- unsigned int frames;
- unsigned int width;
- unsigned int height;
- unsigned int bits;
- unsigned int flags;
- unsigned int speed;
- unsigned long next;
- unsigned long frit;
- unsigned char expand[102];
- } FLIHDR;
-
- typedef struct /* The structure of a frame header */
- {
- unsigned long size;
- unsigned int magic;
- unsigned int chunks;
- unsigned char expand[8];
- } FRAMEHDR;
-
- /*****************************************************************************
- A single routine to open, play, and close a .FLI file. Slow and simple.
- *****************************************************************************/
- vglPlayFLI( char* file, char far* video, int speed )
- {
- register unsigned x;
- register unsigned y;
- char buf[81];
- FILE* fp;
- FLIHDR hdr;
- FRAMEHDR frm;
- unsigned long size;
- unsigned int type;
- unsigned int pakets;
- unsigned char skip;
- unsigned int cnt;
- unsigned int lines;
- unsigned int change;
- signed char s;
- unsigned char v;
- unsigned int i;
- unsigned int c;
- unsigned int f;
- unsigned long vc;
- long RewindPos;
- clock_t tiks;
- char far* vid;
-
- /* Open up the file */
- fp = fopen( file, "rb" );
- if( !fp )
- return 0;
-
- /* Try and allocate a buffer to help speed up the file I/O */
- if( (VBuf = (char*) malloc( BUFSIZE )) == 0 )
- VBuf = (char*) malloc( BUFSIZE / 2 );
- if( VBuf )
- setvbuf( fp, VBuf, _IOFBF, BUFSIZE );
-
- /* Read the header */
- fread( &hdr, sizeof(FLIHDR), 1, fp );
- f = 0;
-
- while( 1 )
- {
- /* For each frame in the flick we... */
- for( ; f <= hdr.frames; f++ )
- {
- tiks = clock();
-
- /* Read in a frame header */
- fread( &frm, sizeof(FRAMEHDR), 1, fp );
-
- /* For each chunk in a frame we... */
- if( frm.size != 0L ) for( i = 0; i < frm.chunks; i++ )
- {
- fread( &size, 1, sizeof(long), fp );
- type = getw( fp );
-
- /* Process each chunk */
- switch( type )
- {
- case FLI_LC : lines = getw( fp );
- change = getw( fp );
- vc = 0;
- y = lines;
- i = y * 320;
- for( c = 0; c < change; c++ )
- {
- vid = video + i;
- i += 320;
- pakets = getc( fp );
- vc++;
- while( pakets-- )
- {
- skip = getc( fp );
- vc++;
- vid += skip;
- s = getc( fp );
- vc++;
- if( s > 0 )
- {
- vc += s;
- while( s-- )
- *vid++ = getc( fp );
- }
- else
- {
- s = -s;
- v = getc( fp );
- vc++;
- while( s-- )
- *vid++ = v;
- }
- }
- y++;
- }
- if( vc & 1 )
- getc( fp );
- break;
- case FLI_BRUN : vc = 0;
- vid = video;
- for( y = 0; y < 200; y++ )
- {
- pakets = getc( fp );
- while( pakets-- )
- {
- vc++;
- s = getc( fp );
- if( s < 0 )
- {
- s = -s;
- vc += s;
- while( s-- )
- *vid++ = getc( fp );
- }
- else
- {
- v = getc( fp );
- vc++;
- while( s-- )
- *vid++ = v;
- }
- }
- }
- if( vc & 1 )
- getc( fp );
- break;
- case FLI_COLOR : vc = 2;
- pakets = getw( fp );
- c = 0;
- while( pakets-- )
- {
- skip = getc( fp );
- vc++;
- c += skip * 3;
- cnt = 0;
- cnt = getc( fp );
- vc++;
- if( cnt == 0 )
- cnt = 256;
- while( cnt-- )
- {
- Pal[c++] = getc( fp );
- Pal[c++] = getc( fp );
- Pal[c++] = getc( fp );
- vc += 3;
- }
- }
- vglSetPal( Pal );
- if( vc & 1 )
- getc( fp );
- break;
- case FLI_COPY : vid = video;
- for( y = 0; y < 200; y++ )
- for( x = 0; x < 320; x++ )
- *vid++ = getc( fp );
- break;
- case FLI_BLACK : vglClear( 0 );
- break;
-
- /* A bad or unknown chuck type (a .FLC perhaps?) */
- default : fclose( fp );
- if( VBuf )
- free( VBuf );
- return 1;
- }
- }
-
- /* If we're writing to a virtual screen, update the real one! */
- if( video != (char far*) 0xa0000000L )
- vglUpdateW();
-
- /* Check for a keypress */
- if( kbhit() )
- {
- if( getch() == 0 )
- getch();
- fclose( fp );
- if( VBuf )
- free( VBuf );
- return 1;
- }
-
- /* Pause the specified number of clock ticks */
- while( clock() - tiks < speed );
-
- if( f == 0 )
- RewindPos = ftell( fp );
- }
- fseek( fp, RewindPos, 0 );
- f = 1;
- }
- }
-
-